package cn.edu.jxau.core.aop;

import java.lang.reflect.Method;

/**
 * Desc:切面模板
 * ------------------------------------
 * Author:fulei04@meituan.com
 * Date:2017/12/20
 * Time:下午3:00
 */
public abstract class AspectTemplate implements Proxy {

    @Override
    public Object doPorxy(ProxyChain proxyChain) throws Throwable {

        Class targetClass = proxyChain.getTargetClass();
        Method targetMethod = proxyChain.getTargetMethod();
        Object[] methodParams = proxyChain.getMethodParams();
        Object result = null;
        begin(); //开始增强
        try {
            if (isIntercept()) {
                before(targetClass, targetMethod, methodParams); //前置增强
                result = proxyChain.doProxyChain();
                after(targetClass, targetMethod, methodParams); //后置增强
            } else {
                result = proxyChain.doProxyChain();
            }
        } catch (Throwable t) {
            throwEx(targetClass, targetMethod, methodParams, t); //异常抛出增强
            throw t;
        } finally {
            end(); //结束增强
        }
        return result;
    }

    /**
     * 是否环绕。如果环绕，会调用{@method before}和{@method after()}
     *
     * @return
     */
    protected boolean isIntercept() {
        return true;
    }

    /**
     * 前置增强
     */
    protected void before(Class targetClass, Method targetMethod, Object[] methodParams) {

    }

    /**
     * 后置增强
     */
    protected void after(Class targetClass, Method targetMethod, Object[] methodParams) {

    }

    /**
     * 开始增强
     */
    protected void begin() {

    }

    /**
     * 结束增强
     */
    protected void end() {

    }

    /**
     * 异常抛出增强
     */
    protected void throwEx(Class targetClass, Method targetMethod, Object[] methodParams, Throwable throwable) {

    }

}
